package com.zt.weibo.utils;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.zt.weibo.WeiboApp;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class AsyncImageLoader {
	private	static	AsyncImageLoader	asyncImageLoader = null;
	//为了加快速度，在内存中开启缓存（主要应用于重复图片较多时，或者同一个图片要多次被访问，比如在ListView时来回滚动）
	private HashMap<String, SoftReference<Bitmap>> imageCache = null;
	private ExecutorService executorService = null; // 固定五个线程来执行任务
	private ArrayList<String> urlList = null;

	public static AsyncImageLoader getInstance(){
		if(asyncImageLoader == null){
			asyncImageLoader = new AsyncImageLoader();
		}
		return asyncImageLoader;
	}

	private AsyncImageLoader(){
		imageCache = new HashMap<String, SoftReference<Bitmap>>();
		executorService = Executors.newFixedThreadPool(5);
		urlList = new ArrayList<String>();
		BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = 4;
	}

	//clear cache, in case the VM is in danger of running out of memory.
	public void clearCache()
	{
		int iListSize = 0;

		if (urlList != null && (iListSize = urlList.size()) > 0)
		{
			int index = 0;

			while(index < iListSize)
			{
				imageCache.remove(urlList.get(index));
				urlList.remove(index);
				iListSize = urlList.size();
				index++;
			}
		}
	}

	/**
	 * 
	 * @param imageUrl
	 *            图像url地址
	 * @param callback
	 *            回调接口
	 * @return 返回内存中缓存的图像，第一次加载返回null
	 */
	private Bitmap loadDrawable(final String imageUrl,
			final ImageCallback callback) {
		// 如果缓存过就从缓存中取出数据
		if (imageCache.containsKey(imageUrl) || urlList.contains(imageUrl)) 
		{
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null)
			{
				return softReference.get();
			}
		}

		// 缓存中没有图像，则从网络上取出数据，并将取出的数据缓存到内存中
		executorService.submit(new Runnable() {
			@Override
			public void run() {
				try {
					final Bitmap image = loadImageFromUrl(imageUrl);
					synchronized (imageCache)
					{
						imageCache.put(imageUrl, new SoftReference<Bitmap>(image));
					}
					
					synchronized (urlList)
					{
						if (!urlList.contains(imageUrl))
						{
							urlList.add(imageUrl);
						}
					}
					
					WeiboApp.mHandler.post(new Runnable() {
						@Override
						public void run() {
							callback.imageLoaded(image);
						}
					});
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
		return null;
	}

	// 从网络上取数据方法
	protected Bitmap loadImageFromUrl(String imageUrl) {
		try {
			return BitmapFactory.decodeStream(new URL(imageUrl).openStream());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	// 对外界开放的回调接口
	public interface ImageCallback {
		// 注意 此方法是用来设置目标对象的图像资源
		public void imageLoaded(Bitmap imageDrawable);
	}
	
	/**
	 * 为传入的ImageView对象设置图片。
	 * @param url 图片地址
	 * @param container 需设置的LinearLayout对象
	 */
	public void loadImage(String url, final LinearLayout container)
	{
		container.setVisibility(View.VISIBLE);
		final ImageView img = (ImageView)container.getChildAt(0);
		Bitmap cacheImage = asyncImageLoader.loadDrawable(url, 
				new AsyncImageLoader.ImageCallback() {
			// 请参见实现：如果第一次加载url时下面方法会执行
			@Override
			public void imageLoaded(Bitmap image)
			{
				if (image != null)
				{
					img.setImageBitmap(image);
				}
			}
		});
		if (cacheImage != null)
		{
			img.setImageBitmap(cacheImage);
		}
	}
	
	/**
	 * 为传入的ImageView对象设置图片。
	 * @param url 图片地址
	 * @param img 需设置的ImageView对象
	 */
	public void loadImage(String url, final ImageView img)
	{
		img.setVisibility(View.VISIBLE);
		Bitmap cacheImage = asyncImageLoader.loadDrawable(url, 
				new AsyncImageLoader.ImageCallback() {
			// 请参见实现：如果第一次加载url时下面方法会执行
			@Override
			public void imageLoaded(Bitmap image)
			{
				if (image != null)
				{
					img.setImageBitmap(image);
				}
			}
		});
		if (cacheImage != null)
		{
			img.setImageBitmap(cacheImage);
		}
	}
	
}

